//============================================================================================
/**
 * @file	lamp.c
 * @brief	ランプ
 * @author	Nozomu Saito
 *
 * モジュール名：Lmp_
 */
//============================================================================================

#include "jump_lamp.h"
#include "../pkthln_act_def.h"
#include "jump_obj_pri.h"

#define NEXT_TIME	(240)	//次の生成までの時間
#define GENE_MAX	(25)		//最大生成数

#define LAMP_X_START1
#define LAMP_X_START2
#define LAMP_X_START3

typedef struct L_POS_tag
{
	u16 X;
	u16 Y;
}L_POS;

typedef struct LAMP_tag
{
	BOOL Valid;
	VecFx32 Pos;
	PKTHLN_ACT_PTR ActPtr;
	PKTHLN_ACT_PTR PtActPtr;
	PKTHLN_ACT_PTR EfActPtr;
}LAMP;

typedef struct LAMP_CNT_tag
{
	LAMP Lamp[LAMP_NUM];
	int NextTime;
}LAMP_CNT;

static void SelectLamp(LAMP *lamp);

static const L_POS LampPos[LAMP_NUM] = {
	{16,8},
	{4,11},
	{12,11},
	{20,11},
	{28,11},
	{8,14},
	{16,14},
	{24,14},
	{4,17},
	{12,17},
	{20,17},
	{28,17},
	{8,20},
	{16,20},
	{24,20},
	{4,23},
	{12,23},
	{20,23},
	{28,23},

	{8,1+24},
	{16,1+24},
	{24,1+24},
	{4,4+24},
	{12,4+24},
	{20,4+24},
	{28,4+24},
	{8,7+24},
	{16,7+24},
	{24,7+24},
};

//--------------------------------------------------------------------------------------------
/**
 * 初期化関数
 *
 * @param	inHeapID	ヒープID
 *
 * @return	cnt_ptr		確保した管理ポインタ
 */
//--------------------------------------------------------------------------------------------
LAMP_CNT_PTR Lmp_Init(const int inHeapID)
{
	int size;
	LAMP_CNT_PTR cnt_ptr;
	size = sizeof(LAMP_CNT);
	cnt_ptr = sys_AllocMemory(inHeapID, size);
	MI_CpuClear8(cnt_ptr, size);

	cnt_ptr->NextTime = 0;
	return cnt_ptr;
}

//--------------------------------------------------------------------------------------------
/**
 * 解放関数
 *
 * @param	cnt_ptr		管理ポインタ
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
void Lmp_End(LAMP_CNT_PTR cnt_ptr)
{
	sys_FreeMemoryEz(cnt_ptr);
}

//--------------------------------------------------------------------------------------------
/**
 * アクターセット
 *
 * @param	cnt_ptr		管理ポインタ
 * @param	pActCntPtr	アクター管理ポインタ
 * @param	inBGPri		BGプライオリティ
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
void Lmp_SetAct(LAMP_CNT_PTR cnt_ptr, PKTHLN_CLACT_CNT_PTR pActCntPtr, const int inBGPri)
{
	int i;
	for(i=0;i<LAMP_NUM;i++){
		cnt_ptr->Lamp[i].ActPtr =
			PkthlnClAct_SetGetActor(pActCntPtr, inBGPri,
									NNS_G2D_VRAM_TYPE_MAX, RES_CODE_JUMP, ACT_CODE_JUMP_LAMP);
		PkthlnClAct_SetActive(cnt_ptr->Lamp[i].ActPtr, 1, 1);	//可視化
		PkthlnClAct_ChgAnm(cnt_ptr->Lamp[i].ActPtr, 8);
		cnt_ptr->Lamp[i].PtActPtr =
			PkthlnClAct_SetGetActor(pActCntPtr, inBGPri,
									NNS_G2D_VRAM_TYPE_MAX, RES_CODE_JUMP, ACT_CODE_JUMP_POINT);
		cnt_ptr->Lamp[i].EfActPtr =
			PkthlnClAct_SetGetActor(pActCntPtr, inBGPri,
									NNS_G2D_VRAM_TYPE_MAX, RES_CODE_JUMP, ACT_CODE_JUMP_GET);
		//プライオリティセット
		PkthlnClAct_SetPriority(cnt_ptr->Lamp[i].ActPtr, PRI_JMP_LAMP);
		PkthlnClAct_SetPriority(cnt_ptr->Lamp[i].PtActPtr, PRI_JMP_POINT);
		PkthlnClAct_SetPriority(cnt_ptr->Lamp[i].EfActPtr, PRI_JMP_GET);
	}
}

//--------------------------------------------------------------------------------------------
/**
 * 表示位置セット
 *
 * @param	cnt_ptr		管理ポインタ
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
void Lmp_SetPos(LAMP_CNT_PTR cnt_ptr)
{
	int i;
	for(i=0;i<LAMP_NUM;i++){
		VecFx32 vec;
		vec.x = LampPos[i].X * 8 * FX32_ONE;
		vec.y = LampPos[i].Y * 8 * FX32_ONE;
		vec.z = 0;
		PkthlnClAct_SetPos(cnt_ptr->Lamp[i].ActPtr, &vec);
		PkthlnClAct_SetPos(cnt_ptr->Lamp[i].PtActPtr, &vec);
		PkthlnClAct_SetPos(cnt_ptr->Lamp[i].EfActPtr, &vec);
		cnt_ptr->Lamp[i].Pos = vec;
	}
}

//--------------------------------------------------------------------------------------------
/**
 * ランプ生成メイン関数
 *
 * @param	cnt_ptr		管理ポインタ
 *
 * @return	TRUE
 */
//--------------------------------------------------------------------------------------------
void Lmp_Generate(LAMP_CNT_PTR cnt_ptr)
{
	int i;
	if (cnt_ptr->NextTime == 0){
		//生成
		SelectLamp(cnt_ptr->Lamp);
		cnt_ptr->NextTime = NEXT_TIME;
	}else{
		cnt_ptr->NextTime--;
	}
}

//--------------------------------------------------------------------------------------------
/**
 * ランプ消灯関数
 *
 * @param	cnt_ptr		管理ポインタ
 * @param	inIdx		対象ランプインデックス
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
void Lmp_Vanish(LAMP_CNT_PTR cnt_ptr, const u8 inIdx)
{
	cnt_ptr->Lamp[inIdx].Valid = FALSE;
	PkthlnClAct_ChgAnm(cnt_ptr->Lamp[inIdx].ActPtr, 8);
}

//--------------------------------------------------------------------------------------------
/**
 * 座標取得
 *
 * @param	cnt_ptr		管理ポインタ
 * @param	inIdx		対象ランプインデックス
 *
 * @return	VecFx32		座標
 */
//--------------------------------------------------------------------------------------------
const VecFx32 *Lmp_GetPos(LAMP_CNT_PTR cnt_ptr, const u8 inIdx)
{
	return &(cnt_ptr->Lamp[inIdx].Pos);
}

//--------------------------------------------------------------------------------------------
/**
 * 有効状態取得
 *
 * @param	cnt_ptr		管理ポインタ
 * @param	inIdx		対象ランプインデックス
 *
 * @return	VecFx32		座標
 */
//--------------------------------------------------------------------------------------------
const BOOL Lmp_IsValid(LAMP_CNT_PTR cnt_ptr, const u8 inIdx)
{
	return cnt_ptr->Lamp[inIdx].Valid;
}

//--------------------------------------------------------------------------------------------
/**
 * 取得ポイント表示
 *
 * @param	cnt_ptr		管理ポインタ
 * @param	inIdx		対象ランプインデックス
 * @param	inPoint		取得ポイント
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
void Lmp_DispPoint(LAMP_CNT_PTR cnt_ptr, const u8 inIdx, const u8 inPoint)
{
	//取得エフェクト
	PkthlnClAct_ChgAnm(cnt_ptr->Lamp[inIdx].EfActPtr, 10);
	PkthlnClAct_SetActive(cnt_ptr->Lamp[inIdx].EfActPtr, 1, 1);
	PkthlnClAct_ChgAnm(cnt_ptr->Lamp[inIdx].PtActPtr, inPoint);
	PkthlnClAct_SetActive(cnt_ptr->Lamp[inIdx].PtActPtr, 1, 1);
}

//--------------------------------------------------------------------------------------------
/**
 * ランプの選定
 *
 * @param	lamp		ランプポインタ
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
static void SelectLamp(LAMP *lamp)
{
	int i;
	int count;
	LAMP *tmp[LAMP_NUM];
	count = 0;
	for(i=0;i<LAMP_NUM;i++){
		if (!lamp[i].Valid){
			//選出対象
			tmp[count++] = &lamp[i];
		}
	}
	//選出対象の中から次の生成ランプを決定
	for(i=0;i<GENE_MAX;i++){
		u8 idx;
		if (count <= 0){
			break;
		}
		idx = gf_rand()%count;
		tmp[idx]->Valid = TRUE;
		PkthlnClAct_ChgAnm(tmp[idx]->ActPtr, 7);

		tmp[idx] = tmp[count-1];
		count--;
	}
}